package com.wontube.smr.bo.sites.youtube.cleanup;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;

import com.wontube.client.extension.utils.StringUtils;
import com.wontube.core.conf.Datasource;
import com.wontube.core.dao.mybatis.QueryExample;
import com.wontube.smr.client.model.po.Mp3Url;
import com.wontube.smr.client.model.po.VideoPage;
import com.wontube.smr.dao.mapper.Mp3UrlMapper;
import com.wontube.smr.dao.mapper.VideoPageMapper;
import com.wontube.smr.dao.mapper.VideoUrlMapper;
import com.wontube.smr.pub.DefaultDBHelper;




/**
 * @author yuechao
 * 
 */
public final class CleanupBO {
	private CleanupBO() {
	}

	/**
	 * 清理过期mp3，由于时间比较长，因为注意防止事务超时
	 * 
	 * @return 返回删除的文件数量
	 */
	public static int cleanupMp3(int minVersion, int minDownTimes) {
		int deleteCount = 0;
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, minVersion);

		QueryExample ex = new QueryExample();
		ex.or().addCriterion("down_times < ", minDownTimes)
			.addCriterion("version < ", calendar.getTime());

		while (true) {
			SqlSession session = DefaultDBHelper.getBatchSqlSession();
			Mp3UrlMapper mapper = session.getMapper(Mp3UrlMapper.class);
			try {
				RowBounds bounds = new RowBounds(0, 1000);
				List<Mp3Url> list = mapper.selectByExample(ex, bounds);
				if (list.size() < 1) {
					break;
				}
				for (Mp3Url mp3Url : list) {
					String filename = StringUtils.format("{}/mp3/youtube/{}/{}.mp3", Datasource.getDefaultDataSource()
							.getDataPath(), mp3Url.getPath(), mp3Url.getId());
					File file = new File(filename);
					if (file.isFile() && file.exists()) {
						file.delete();
						deleteCount++;
					}

					mapper.deleteByPrimaryKey(mp3Url.getId());

					VideoUrlMapper videoUrlMapper = session.getMapper(VideoUrlMapper.class);
					QueryExample queryEx = new QueryExample();
					queryEx.or().addCriterion("page_id = ", mp3Url.getPageId());
					videoUrlMapper.deleteByExample(queryEx);
				}

				session.commit();
			} finally {
				session.close();
			}
		}

		return deleteCount;
	}

	/**
	 * 清理过期video数据，因为执行过程比较长，因此注意防止事务超时
	 * 
	 * @return 返回删除的记录数量
	 */
	public static int cleanupVideo(int minVersion, int minVisitTimes) {
		int deleteCount = 0;

		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, minVersion);

		// 未被mp3引用
		QueryExample ex = new QueryExample();
		ex.or().addCriterion("visit_times < ", minVisitTimes)
			.addCriterion("version < ", calendar.getTime())
			.addCriterion("id not in (select page_id from mp3_url)");

		while (true) {
			SqlSession session = DefaultDBHelper.getBatchSqlSession();
			try {
				VideoUrlMapper videoUrlMapper = session.getMapper(VideoUrlMapper.class);
				
				VideoPageMapper mapper = session.getMapper(VideoPageMapper.class);
				RowBounds bounds = new RowBounds(0, 20000);
				List<VideoPage> list = mapper.selectByExample(ex, bounds);

				if (list.size() < 1) {
					break;
				}

				for (VideoPage page : list) {
					QueryExample queryEx = new QueryExample();
					queryEx.or().addCriterion("page_id = ", page.getId());

					deleteCount += videoUrlMapper.deleteByExample(queryEx);
					deleteCount += mapper.deleteByPrimaryKey(page.getId());
				}
				session.commit();
			} finally {
				session.close();
			}
		}

		// 删除videoUrl
		calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -1);
		int delVideoUrlCount = 0;
		do {
			SqlSession session = DefaultDBHelper.getSqlSession(false);
			try {
				// 限制最大数量，循环删除，防止内存溢出
				ex = new QueryExample();
				String condition = StringUtils.format(
						"page_id in (select id from video_page where version < '{}' limit 1000)",
						new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
				ex.or().addCriterion(condition);
				VideoUrlMapper videoUrlMapper = session.getMapper(VideoUrlMapper.class);
				delVideoUrlCount = videoUrlMapper.deleteByExample(ex);
				deleteCount += delVideoUrlCount;

				session.commit();
			} finally {
				session.close();
			}
		} while (delVideoUrlCount > 0);

		return deleteCount;
	}
}
